/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author brett
 */

import java.io.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import ucar.ma2.ArrayFloat;     // for netCDF reader
import ucar.ma2.IndexIterator;  // for netCDF reader
import ucar.nc2.Dimension;
import ucar.nc2.NetcdfFile;     // for netCDF reader
import ucar.nc2.Variable;       // for netCDF reader



public class InputAdapter {
    
    public static double[][] read2DVariable(String fileName, String varName, int xRng, int yRng) {
        
        // VARIABLES
        NetcdfFile inputFile = null;    // target netCDF file
        Variable ncdfVar;            // E-W, N-S wind speed NetCDF variables
        ArrayFloat.D3 d3Var;         // 3D NetCDF float array
        List<Variable> inputVariables; 
        double[][] results;
        
        // initialize results
        results = new double[xRng][yRng];
                
        try {
            // open target netCDF file

            inputFile = NetcdfFile.open(fileName, null);    // Open the file

            // Find target variable
            ncdfVar = inputFile.findVariable(varName);
        

            // Get list of file's variables
            inputVariables = inputFile.getVariables();
            ncdfVar = inputVariables.get(inputVariables.indexOf(ncdfVar));


            // Read values from variable
            d3Var = (ArrayFloat.D3) ncdfVar.read();

            // Iterators
            IndexIterator iter;
            iter = d3Var.getIndexIterator();

            int x = 0;
            int y = 0;

            // Fill arrays with values from file
            while (iter.hasNext()) {
                iter.next();

                results[x][y] = (double) iter.getFloatCurrent();

                // iterating through 2 dimensions
                if (x == xRng - 1) {
                    y++;
                    x = 0;
                } else {
                    x++;
                }
            }

//            return results;
        } catch (java.io.IOException e) {
            e.printStackTrace();

        } catch (Exception e) {
            e.printStackTrace();

        } finally {                 // Close out the file no matter what occurs
            if (inputFile != null) {
                try {
                    inputFile.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }

        }
                    if (results == null) System.err.println("In input adapter: null results");
            System.err.println("In input adapter: "  + results[2][3]);
        return results;

    }
    
    public static double[][][] read2DVariables(String fileName, String[] varNames, int xRng, int yRng) {
        // VARIABLES
        double[][][] results;
        double[][] tempResults;
        
        // initialize results
        int lng = varNames.length;
        results = new double[xRng][yRng][lng];
        tempResults = new double[xRng][yRng];

        for (int i = 0; i < lng; ++i) {
            tempResults = read2DVariable(fileName, varNames[i], xRng, yRng);
            results[i] = tempResults;
        }
        
        return results;
    }
    
       
    public static double[][][] read3DVariable(String fileName, String varName, int xRng, int yRng, int zRng) {
                
        // VARIABLES
        NetcdfFile inputFile = null;    // target netCDF file
        Variable ncdfVar;            // E-W, N-S wind speed NetCDF variables
        ArrayFloat.D3 d3Var;         // 3D NetCDF float array
        List<Variable> inputVariables; 
        double[][][] results;
        
        // initialize results
        results = new double[xRng][yRng][zRng];
                
        try {
            // open target netCDF file

            inputFile = NetcdfFile.open(fileName, null);    // Open the file

            // Find target variable
            ncdfVar = inputFile.findVariable(varName);
        

            // Get list of file's variables
            inputVariables = inputFile.getVariables();
            ncdfVar = inputVariables.get(inputVariables.indexOf(ncdfVar));


            // Read values from variable
            d3Var = (ArrayFloat.D3) ncdfVar.read();

            // Iterators
            IndexIterator iter;
            iter = d3Var.getIndexIterator();

            int x = 0;
            int y = 0;
            int z = 0;

            // Fill arrays with values from file
            while (iter.hasNext()) {
                iter.next();

                results[x][y][z] = (double) iter.getFloatCurrent();

                // iterating through 3 dimensions
                if (x == xRng - 1) {
                    x = 0;
                    if (y == yRng - 1) {
                        y = 0;
                        ++z;
                    }
                    else {
                        ++y;
                    }
                } 
                else  {
                    ++x;
                }
            }

        } catch (java.io.IOException e) {
            e.printStackTrace();

        } catch (Exception e) {
            e.printStackTrace();

        } finally {                 // Close out the file no matter what occurs
            if (inputFile != null) {
                try {
                    inputFile.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }

        }
        return results;
    }
    
    public static double[][][][] read3DVariables(String fileName, String[] varNames, int xRng, int yRng, int zRng) {
        // VARIABLES
        double[][][][] results;
        double[][][] tempResults;
        
        // initialize results
        int lng = varNames.length;
        results = new double[xRng][yRng][zRng][lng];
        tempResults = new double[xRng][yRng][zRng];

        for (int i = 0; i < lng; ++i) {
            tempResults = read3DVariable(fileName, varNames[i], xRng, yRng, zRng);
            results[i] = tempResults;
        }
        
        return results;
    }
    
    public static int[] getRanges(String fileName, String varName) throws IOException {
        NetcdfFile inputFile = null;    // target netCDF file
        Variable ncdfVar;            // E-W, N-S wind speed NetCDF variables
        try {
            inputFile = NetcdfFile.open(fileName, null);    // Open the file
            // Find target variable
            ncdfVar = inputFile.findVariable(varName);
            
            List<Dimension> dimensions = ncdfVar.getDimensions();
            ListIterator<Dimension> dIter = dimensions.listIterator();
            
            int[] ranges = new int[dimensions.size()];
            int counter = 0;
            while (dIter.hasNext()) {
                ranges[counter] = dIter.next().getLength();
                ++counter;
            }
            
            return ranges;
            
        } catch (IOException ex) {
            Logger.getLogger(InputAdapter.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            if (inputFile != null) {
                inputFile.close();
            }
            return null;
        }

            
        
    }
    
    public static int getDimensions(String fileName, String varName) {
                
        NetcdfFile inputFile = null;    // target netCDF file
        Variable ncdfVar;            // E-W, N-S wind speed NetCDF variables
        try {
            inputFile = NetcdfFile.open(fileName, null);    // Open the file
            // Find target variable
            ncdfVar = inputFile.findVariable(varName);
            
            return ncdfVar.getDimensions().size();
            
        } catch (IOException ex) {
            Logger.getLogger(InputAdapter.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            if (inputFile != null) {
                try {
                    inputFile.close();
                } catch (IOException ex) {
                    Logger.getLogger(InputAdapter.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            return -1;
        }

            
    }
        
    
    
    
}
